﻿using System.Diagnostics;
using JetBlack.Diagnostics;
using JetBlack.Services;
using System;

namespace JetBlack.AuthFeedBus.Distributor
{
    /// <summary>
    /// The server for distributor.
    /// </summary>
    public class Server : StateManagedServer
    {
        private Acceptor acceptor = null;
        private Market market = null;

        /// <summary>
        /// The method called to start the distributor.
        /// </summary>
        /// <param name="args">The startup arguments.</param>
        /// <returns>If successful, true is returned.</returns>
        protected override bool OnStart(string[] args)
        {
            if (AppEnvironment.Configuration == null)
            {
                TraceSource.Critical("Unable to read configuration");
                return false;
            }

            try
            {
                ProcessArgs(args);
            }
            catch (Exception ex)
            {
                AppEnvironment.TraceSource.Error("Failed to process arguments", ex);
                return false;
            }

            market = new Market();
            market.Start();

            acceptor = new Acceptor();
            acceptor.OnClientOpened += market.AddClient;
            acceptor.OnClientClosed += market.RemoveClient;
            acceptor.OnClientMessage += market.HandleClientMessage;

            acceptor.Start();

            return true;
        }

        /// <summary>
        /// Stop the distributor.
        /// </summary>
        protected override void OnStop()
        {
            acceptor.Dispose();
            market.Dispose();
        }

        /// <summary>
        /// The distributor cannot be paused.
        /// </summary>
        /// <returns></returns>
        protected override bool OnPause()
        {
            return false;
        }

        /// <summary>
        /// The distributor cannot be resumed.
        /// </summary>
        /// <returns></returns>
        protected override bool OnResume()
        {
            return false;
        }

        /// <summary>
        /// The logger.
        /// </summary>
        public override TraceSource TraceSource
        {
            get { return AppEnvironment.TraceSource; }
        }

        private void ProcessArgs(string[] args)
        {
            foreach (var arg in args)
            {
                var parts = arg.Split(':');
                switch (parts[0])
                {
                    case "/port":
                        if (parts.Length != 2)
                            throw new ArgumentException("Missing integer port", "/port");
                        AppEnvironment.Configuration.Port = int.Parse(parts[1]);
                        break;
                    default:
                        throw new ArgumentException("Unknown argument", parts[0]);
                }
            }
        }
    }
}
